﻿using System;
using System.Diagnostics;
using System.Windows;
using DeepMixWorkflow;
using Microsoft.Phone.BackgroundAudio;

namespace DeepmixPlaybackAgent
{
    public class AudioPlayer : AudioPlayerAgent
    {
        private static volatile bool _classInitialized;
        
        public AudioPlayer()
        {
            CommonHelper.Log("Вызван конструктор AudioPlayer");
            if (!_classInitialized)
            {
                _classInitialized = true;
                // Subscribe to the managed exception handler
                Deployment.Current.Dispatcher.BeginInvoke(
                    delegate { Application.Current.UnhandledException += AudioPlayer_UnhandledException; });
            }
        }
        
        private void AudioPlayer_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
        {
            CommonHelper.Log("Непредвиденная ошибка в AudioPlayer: {0}", e.ExceptionObject);
            if (Debugger.IsAttached)
            {
                Debugger.Break();
            }

#if !DEBUG
            e.Handled = true;
#endif
        }
        
        protected override void OnPlayStateChanged(BackgroundAudioPlayer player, AudioTrack track, PlayState playState)
        {
            CommonHelper.Log("PlayStateCHanged: " + playState);
            switch (playState)
            {
                case PlayState.TrackEnded:
                    if (track != null)
                        if (track.Tag != null)
                        {
                            string uri;
                            var deepMixMode = track.Tag.GetDeepMixMode(out uri);

                            if (deepMixMode == DeepMixMode.OnAir)
                            {
                                CallOnAirAgain();
                                return;
                            }
                            if (deepMixMode == DeepMixMode.Selected)
                            {
                                SetNextTrackFrom(CommonHelper.FromAudioTrack(track));
                            }
                        }

                    break;
                case PlayState.TrackReady:
                    player.Play();
                    break;
                case PlayState.BufferingStopped:
                    BackgroundAudioPlayer.Instance.Play();
                    break;
                case PlayState.Shutdown:
                case PlayState.Unknown:
                case PlayState.Stopped:
                case PlayState.Paused:
                case PlayState.Playing:
                case PlayState.BufferingStarted:
                case PlayState.Rewinding:
                case PlayState.FastForwarding:
                    break;
            }
            NotifyComplete();
        }


        private void SetPrevTrackFrom(DeepMixTrack track)
        {
            var selectedTracks = LoadSelected();
            if (selectedTracks != null)
                for (int index = 0; index < selectedTracks.Length; index++)
                {
                    DeepMixTrack selectedTrack = selectedTracks[index];
                    if (selectedTrack.Link == track.Link)
                    {
                        int ind = index - 1;
                        if (ind == -1) ind = selectedTracks.Length - 1;
                        DeepMixTrack ttp = selectedTracks[ind];

                        BackgroundAudioPlayer.Instance.Volume = 1;
                        BackgroundAudioPlayer.Instance.Track = new AudioTrack(null, ttp.Title, ttp.Artist,
                                                                              AppResources.Selected, null,
                                                                              TagParser.CreateSelected(ttp.Link),
                                                                              EnabledPlayerControls.SkipNext |
                                                                              EnabledPlayerControls.SkipPrevious |
                                                                              EnabledPlayerControls.Pause);
                        return;
                    }
                }
        }

        private void SetNextTrackFrom(DeepMixTrack track)
        {
            var selectedTracks = LoadSelected();
            if (selectedTracks != null)
                for (int index = 0; index < selectedTracks.Length; index++)
                {
                    var selectedTrack = selectedTracks[index];

                    if (selectedTrack.Link == track.Link)
                    {
                        int ind = index + 1;
                        if (ind == selectedTracks.Length) ind = 0;
                        DeepMixTrack ttp = selectedTracks[ind];
                        BackgroundAudioPlayer.Instance.Volume = 1;
                        BackgroundAudioPlayer.Instance.Track = new AudioTrack(null, ttp.Title, ttp.Artist,
                                                                              AppResources.Selected, null,
                                                                              TagParser.CreateSelected(ttp.Link),
                                                                              EnabledPlayerControls.SkipNext |
                                                                              EnabledPlayerControls.SkipPrevious |
                                                                              EnabledPlayerControls.Pause);
                        return;
                    }
                }
        }

        private DeepMixTrack[] LoadSelected()
        {
            return StorageContainer.Selected.Value.Tracks;
        }

        private void CallOnAirAgain()
        {
            CommonHelper.Log("Трек закончился и это эфир, запускаем его опять");

            CommonHelper.GetNowPlayingTrack(track =>
                {
                    CommonHelper.Log("Итак, запускаем эфир опять");
                    BackgroundAudioPlayer.Instance.Volume = 1;
                    BackgroundAudioPlayer.Instance.Track = new AudioTrack(null,
                                                                          track
                                                                              .
                                                                              Title,
                                                                          track
                                                                              .
                                                                              Artist,
                                                                          AppResources.Radio,
                                                                          null,
                                                                          TagParser
                                                                              .
                                                                              CreateOnAir
                                                                              (),
                                                                          EnabledPlayerControls
                                                                              .
                                                                              Pause);

                    NotifyComplete();
                },exception =>
                {
                    CommonHelper.SayErrcommor();
#if DEBUG
                    throw exception;
#else
                    NotifyComplete();
#endif
                });
        }


        protected override void OnUserAction(BackgroundAudioPlayer player, AudioTrack track, UserAction action,
                                             object param)
        {
            CommonHelper.Log("ONUserAction: " + action);
            switch (action)
            {
                case UserAction.Play:
                    if (player.PlayerState != PlayState.Playing)
                    {
                        CommonHelper.Log("Вызван Play и tag !=null");
                        player.Track = track;
                    }
                    break;
                case UserAction.Stop:
                    if (player.PlayerState != PlayState.Unknown)
                        player.Stop();
                    break;
                case UserAction.Pause:
                    if (player.PlayerState != PlayState.Paused)
                    {
                        if (track != null)
                        {
                            string s;
                            var deepMixMode = track.Tag.GetDeepMixMode(out s);
                            if (deepMixMode == DeepMixMode.OnAir) player.Stop();
                            else
                            {
                                player.Pause();
                            }
                        }
                        else
                        {
                            player.Pause();
                        }
                    }
                    break;
                case UserAction.SkipNext:
                    string uri;
                    if (track != null)
                    {
                        var deepMixMode = track.Tag.GetDeepMixMode(out uri);

                        if (deepMixMode == DeepMixMode.Selected)
                        {
                            SetNextTrackFrom(CommonHelper.FromAudioTrack(track));
                        }
                    }
                    break;
                case UserAction.SkipPrevious:
                    if (track != null)
                    {
                        var deepMixMode = track.Tag.GetDeepMixMode(out uri);

                        if (deepMixMode == DeepMixMode.Selected)
                        {
                            SetPrevTrackFrom(CommonHelper.FromAudioTrack(track));
                        }
                    }
                    break;
                default:
                    throw new NotSupportedException("Unsupported");
            }

            NotifyComplete();
        }

        protected override void OnError(BackgroundAudioPlayer player, AudioTrack track, Exception error, bool isFatal)
        {
            if(Debugger.IsAttached)Debugger.Break();

            //player.SkipNext();
            CommonHelper.Log("OnError:" + error + " IsFatal:" + isFatal);
            if (isFatal)
            {
                Abort();
            }
            else
            {
                NotifyComplete();
            }
        }

        /// <summary>
        /// Called when the agent request is getting cancelled
        /// </summary>
        /// <remarks>
        /// Once the request is Cancelled, the agent gets 5 seconds to finish its work,
        /// by calling NotifyComplete()/Abort().
        /// </remarks>
        protected override void OnCancel()
        {
            CommonHelper.Log("OnCancel PlayerAgent вызван");
            NotifyComplete();
        }
    }
}